package com.lwq.fast.log.fastlogserver.init.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.lwq.fast.log.fastlogcore.constant.Constants;
import com.lwq.fast.log.fastlogcore.entity.AppEnvIndex;
import com.lwq.fast.log.fastlogserver.common.util.AppNameEnvCacheUtil;
import com.lwq.fast.log.fastlogserver.es.service.ElasticSearchService;
import com.lwq.fast.log.fastlogserver.init.service.IndexInitializeService;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 索引初始化
 * @author  刘文强
 */
@Service
public class IndexInitializeServiceImpl implements IndexInitializeService {


    @Autowired
    private ElasticSearchService elasticSearchService;
    @Autowired
    private RestHighLevelClient restHighLevelClient;
    /**
     * 初始化默认索引信息
     */
    @Override
    public void initializeIndex() throws Exception {

        initializeAppNameIndex();

        initializeEnvIndex();

        initializeCache();

    }


    /**
     * 初始化应用名称和环境名称缓存信息
     */
    private void initializeCache() throws Exception{
        // 所有应用名称缓存
        List<String> allAppNames = elasticSearchService.getAllAppNames();
        if (CollectionUtil.isNotEmpty(allAppNames)){
            allAppNames.forEach(entity ->{
                AppNameEnvCacheUtil.setAppNameCache(entity, entity);
            });
        }
        // 所有环境信息缓存
        List<AppEnvIndex> allEnv = elasticSearchService.getAllEnv();
        if (CollectionUtil.isNotEmpty(allEnv)){
            allEnv.forEach(entity ->{
                AppNameEnvCacheUtil.setEnvCache(entity.getEnv(), entity.getEnv());
            });
        }
        // 所有索引的缓存
        List<String> indices = elasticSearchService.getAllIndices();
        if (CollectionUtil.isNotEmpty(indices) && CollectionUtil.isNotEmpty(allAppNames)){
            Set<String> appNameSet = allAppNames.stream().collect(Collectors.toSet());
            List<String> allIndexList = indices.stream().filter(entity -> appNameSet.contains(entity)).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(allIndexList)){
                allIndexList.forEach(entity ->{
                    AppNameEnvCacheUtil.setIndicesCache(entity,entity);
                });
            }
        }
    }

    /**
     * 初始化环境信息索引
     * @throws IOException
     */
    private void initializeEnvIndex() throws IOException {
        boolean existEnvIndex = elasticSearchService.existIndex(Constants.APP_ENV_INDEX);
        if (!existEnvIndex){
            // 创建 env索引

            CreateIndexRequest request = new CreateIndexRequest(Constants.APP_ENV_INDEX);
            //索引setting
            request.settings(Settings.builder()
                    .put("index.number_of_shards", 1)
                    .put("index.number_of_replicas", 1));
            //索引mapping
            XContentBuilder builder = XContentFactory.jsonBuilder();
            builder.startObject();
            {
                builder.startObject("properties");
                {
                    builder.startObject("env");
                    {
                        builder.field("type", "text");
                    }
                    builder.endObject();

                    builder.startObject("envDesc");
                    {
                        builder.field("type", "text");
                    }
                    builder.endObject();
                }
                builder.endObject();
            }
            builder.endObject();
            request.mapping(builder);
            restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
        }
    }

    /**
     * 初始化 appname 索引
     * @throws IOException
     */
    private void initializeAppNameIndex() throws IOException {
        boolean existAppName = elasticSearchService.existIndex(Constants.APP_NAME_INDEX);
        if (!existAppName){
            // 创建 appName索引
            CreateIndexRequest request = new CreateIndexRequest(Constants.APP_NAME_INDEX);
            //索引setting
            request.settings(Settings.builder()
                    .put("index.number_of_shards", 1)
                    .put("index.number_of_replicas", 1));
            //索引mapping
            XContentBuilder builder = XContentFactory.jsonBuilder();
            builder.startObject();
            {
                builder.startObject("properties");
                {
                    builder.startObject("appName");
                    {
                        builder.field("type", "text");
                    }
                    builder.endObject();
                }
                builder.endObject();
            }
            builder.endObject();
            request.mapping(builder);
            restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
        }
    }
}
